<template>
  <div class="chart-item">
    <div v-if="showTypeToggle" class="chart-type-toggle">
      <el-radio-group v-model="currentChartType" size="small">
        <el-radio-button label="bar">柱状图</el-radio-button>
        <el-radio-button label="line">折线图</el-radio-button>
      </el-radio-group>
    </div>
    <div class="chart" :id="chartId"></div>
  </div>
</template>

<script>
import * as echarts from 'echarts'
import {debounce} from 'lodash-es'

export default {
  name: "EnhancedBarChart",
  props: {
    chartType: {
      type: String,
      default: 'bar',
      validator: v => ['bar', 'line'].includes(v)
    },
    yAxisFormatter: Function,
    showTypeToggle: {
      type: Boolean,
      default: true
    },
    dataType: String,
    list: {
      type: [Object, Array],
      required: true
    },
    selectId: [String, Number]
  },
  data() {
    return {
      chart: null,
      chartId: `chart-${Math.random().toString(36).substr(2, 9)}`,
      currentChartType: this.chartType
    }
  },
  watch: {
    currentChartType: {
      handler: 'updateChart',
      immediate: true
    },
    dataType: {
      handler: 'updateChart'
    },
    selectId: {
      handler: 'updateChart'
    },
    list: {
      handler: 'updateChart',
      deep: true
    }
  },
  methods: {
    initChart() {
      if (!this.chart) {
        const chartDom = document.getElementById(this.chartId)
        if (!chartDom) return

        this.chart = echarts.init(chartDom)
        this.chart.showLoading({
          text: '加载中',
          textColor: '#fff',
          maskColor: 'rgba(0,0,0,0)'
        })

        // 添加窗口resize监听
        window.addEventListener('resize', this.handleResize)
      }
      this.updateChart()
    },

    getCurrentData() {
      // 处理对象类型数据源
      if (typeof this.list === 'object' && !Array.isArray(this.list)) {
        return this.list[this.dataType] || {}
      }

      // 处理数组类型数据源
      if (Array.isArray(this.list)) {
        return this.list.find(item => item.selectId === this.selectId) || {}
      }

      return {}
    },

    getXAxisConfig(xData) {
      return {
        type: 'category',
        data: xData || [],
        axisLabel: {
          color: '#A3A3C9',
          rotate: 50,
          formatter: this.axisLabelFormatter
        },
        axisLine: {
          lineStyle: {
            color: '#0B3771'
          }
        },
        axisTick: {show: false}
      }
    },

    getYAxisConfig() {
      return {
        type: 'value',
        axisLabel: {
          color: '#A3A3C9',
          formatter: this.yAxisFormatter || '{value}'
        },
        splitLine: {
          lineStyle: {
            color: 'rgba(199,199,200,0.1)',
            type: 'dashed'
          }
        }
      }
    },

    getSeriesConfig(yData) {
      const isLineChart = this.currentChartType === 'line'

      return [{
        data: yData || [],
        type: this.currentChartType,
        barWidth: 15,
        smooth: isLineChart,
        symbol: isLineChart ? 'circle' : 'none',
        symbolSize: 8,
        lineStyle: {
          width: isLineChart ? 3 : 0
        },
        itemStyle: this.getItemStyle(),
        label: this.getLabelConfig(),
        emphasis: {
          itemStyle: {
            shadowBlur: 10,
            shadowColor: 'rgba(14, 237, 251, 0.5)'
          }
        }
      }]
    },

    getChartOption() {
      const {xData, yData} = this.getCurrentData()

      return {
        grid: {
          right: 30,
          bottom: 60,
          top: this.showTypeToggle ? 40 : 20,
          left: 40,
          containLabel: true
        },
        tooltip: {
          trigger: 'axis',
          formatter: params => {
            if (this.yAxisFormatter) {
              return `${params[0].axisValue}<br/>${this.yAxisFormatter(params[0].value)}`
            }
            return params[0].value
          }
        },
        xAxis: this.getXAxisConfig(xData),
        yAxis: this.getYAxisConfig(),
        series: this.getSeriesConfig(yData)
      }
    },

    updateChart() {
      if (!this.chart) return

      try {
        const option = this.getChartOption()
        this.chart.setOption(option, true)
        this.chart.hideLoading()
      } catch (e) {
        console.error('图表更新失败:', e)
      }
    },

    axisLabelFormatter(value) {
      const maxLength = 5
      if (value.length <= maxLength) return value

      const rows = Math.ceil(value.length / maxLength)
      return value.split('').reduce((acc, char, index) => {
        if (index % maxLength === 0 && index !== 0) acc += '\n'
        return acc + char
      }, '')
    },

    handleResize: debounce(function () {
      this.chart?.resize()
    }, 300),

    getItemStyle() {
      return this.currentChartType === 'bar' ? {
        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
          {offset: 0, color: '#0EEDFB'},
          {offset: 1, color: '#10294e'}
        ]),
        opacity: 0.8
      } : {
        color: '#0EEDFB'
      }
    },

    getLabelConfig() {
      return {
        show: true,
        position: 'top',
        color: '#fff',
        formatter: params => {
          return this.yAxisFormatter
              ? this.yAxisFormatter(params.value)
              : params.value
        }
      }
    }
  },
  mounted() {
    this.$nextTick(this.initChart)
  },
  beforeDestroy() {
    if (this.chart) {
      window.removeEventListener('resize', this.handleResize)
      this.chart.dispose()
      this.chart = null
    }
  }
}
</script>

<style scoped>
.chart-item {
  position: relative;
  width: 100%;
  height: 100%;
}

.chart-type-toggle {
  position: absolute;
  right: 20px;
  top: 10px;
  z-index: 10;
}

.chart {
  width: 100%;
  height: 400px;
}

@media (max-width: 768px) {
  .chart {
    height: 300px;
  }

  .chart-type-toggle {
    right: 10px;
    top: 5px;
  }
}
</style>
